home *** CD-ROM | disk | FTP | other *** search
/ Aminet 34 / Aminet 34 (2000)(Schatztruhe)[!][Dec 1999].iso / Aminet / dev / lang / jlint.lha / jlint.h < prev    next >
C/C++ Source or Header  |  1999-05-18  |  20KB  |  856 lines

  1. //-< JLINT.H >-------------------------------------------------------*--------*
  2. // Jlint                      Version 1.09       (c) 1998  GARRET    *     ?  *
  3. // (Java Lint)                                                       *   /\|  *
  4. //                                                                   *  /  \  *
  5. //                          Created:     28-Mar-98    K.A. Knizhnik  * / [] \ *
  6. //                          Last update: 20-Aug-98    K.A. Knizhnik  * GARRET *
  7. //-------------------------------------------------------------------*--------*
  8. // Java verifier 
  9. //-------------------------------------------------------------------*--------*
  10.  
  11. #ifndef __JLINT_H__
  12. #define __JLINT_H__
  13.  
  14. #define VERSION 1.09
  15.  
  16. typedef int      int4;
  17. typedef unsigned nat4;
  18.  
  19. #if defined(_WIN32)
  20. #define INT8_DEFINED 1
  21. typedef __int64 int8;
  22. typedef unsigned __int64 nat8;
  23. #else
  24. #if defined(__osf__ )
  25. #define INT8_DEFINED 1
  26. typedef   signed long int8;
  27. typedef unsigned long nat8;
  28. #else
  29. #if defined(__GNUC__)
  30. #define INT8_DEFINED 1
  31. typedef long long          int8;
  32. typedef unsigned long long nat8;
  33. #endif
  34. #endif
  35. #endif
  36.  
  37. #define bool  int
  38. #define true  1
  39. #define false 0
  40.  
  41. #define nobreak 
  42.  
  43. typedef unsigned char  byte;
  44. typedef unsigned short word;
  45.  
  46. enum vbm_instruction_code { 
  47. #define JAVA_INSN(code, mnem, len) mnem,
  48. #include "jlint.d"
  49. last_insn
  50. };
  51.     
  52. #define   items(array) (sizeof(array)/sizeof*(array))
  53.  
  54. inline int unpack2(byte* s) { 
  55.     return (s[0] << 8) + s[1]; 
  56. }
  57.  
  58. inline int unpack4(byte* s) { 
  59.     return (((((s[0] << 8) + s[1]) << 8) + s[2]) << 8) + s[3];
  60.  
  61. inline int unpack2_le(byte* s) { 
  62.     return (s[1] << 8) + s[0]; 
  63. }
  64.  
  65. inline int unpack4_le(byte* s) { 
  66.     return (((((s[3] << 8) + s[2]) << 8) + s[1]) << 8) + s[0];
  67.  
  68. enum type_tag { 
  69.     tp_bool,
  70.     tp_byte,
  71.     tp_char,
  72.     tp_short,
  73.     tp_int,
  74.     tp_long,
  75.     tp_float,
  76.     tp_double,
  77.     tp_void, 
  78.     tp_self,
  79.     tp_string,
  80.     tp_object
  81. };
  82.  
  83. #define IS_INT_TYPE(tp) (tp <= tp_int)
  84. #define IS_ARRAY_TYPE(tp) ((tp & ~0xFF) != 0)
  85.  
  86. struct int_type_range { 
  87.     int4 min;
  88.     int4 max;
  89. };
  90.  
  91.  
  92. enum message_category { 
  93.     cat_deadlock        = 0x00000001, 
  94.     cat_race_condition  = 0x00000002,
  95.     cat_wait_nosync     = 0x00000004,
  96.     cat_synchronization = 0x0000000F,
  97.  
  98.     cat_super_finalize  = 0x00000010,
  99.     cat_not_overridden  = 0x00000020,
  100.     cat_field_redefined = 0x00000040,
  101.     cat_shadow_local    = 0x00000080,
  102.     cat_inheritance     = 0x000000F0,
  103.  
  104.     cat_zero_operand    = 0x00000100,
  105.     cat_zero_result     = 0x00000200, 
  106.     cat_redundant       = 0x00000400,
  107.     cat_overflow        = 0x00000800, 
  108.     cat_incomp_case     = 0x00001000,
  109.     cat_short_char_cmp  = 0x00002000,
  110.     cat_string_cmp      = 0x00004000,
  111.     cat_weak_cmp        = 0x00008000,
  112.     cat_domain          = 0x00010000,
  113.     cat_null_reference  = 0x00020000,
  114.     cat_truncation      = 0x00040000,
  115.     cat_bounds          = 0x00080000,
  116.     cat_data_flow       = 0x000FFF00,
  117.  
  118.     cat_done            = 0x10000000,
  119.  
  120.     cat_all             = 0xFFFFFFFF
  121. };
  122.  
  123. struct message_descriptor {
  124.     message_category category;
  125.     const char*      format;
  126.     const char*      name;
  127.     bool             position_dependent;
  128.     bool             enabled;
  129. };
  130.  
  131. class message_node {
  132.     static message_node* hash_table[];
  133.   public:
  134.     message_node* next;
  135.     char*         text;
  136.  
  137.     static bool find(char* msg);
  138.     static void add_to_hash(char* msg);
  139.  
  140.     message_node(char* msg) { 
  141.     text = strdup(msg);
  142.     next = NULL;
  143.     }
  144.     ~message_node() { delete[] text; }
  145. };
  146.  
  147.  
  148.  
  149. enum message_code { 
  150. #define MSG(category, code, pos, text) msg_##code,
  151. #include "jlint.msg"
  152. msg_last
  153. };
  154.  
  155. #define MSG_LOCATION_PREFIX "%0s:%1d: " // Emacs style: "file:line_number: "
  156.  
  157. #define MAX_MSG_LENGTH      1024
  158. #define MAX_MSG_PARAMETERS  16
  159.  
  160. struct msg_select_category_option { 
  161.     message_category msg_cat;
  162.     const char*      cat_name;
  163.     const char*      cat_desc;
  164. };
  165.  
  166. extern unsigned string_hash_function(byte* p);
  167.  
  168. class utf_string {
  169.   protected:
  170.     int   len;
  171.     byte* data;
  172.  
  173.   public:
  174.     bool operator == (utf_string const& str) const { 
  175.     return len == str.len && memcmp(data, str.data, len) == 0; 
  176.     }
  177.     bool operator != (utf_string const& str) const { 
  178.     return len != str.len || memcmp(data, str.data, len) != 0; 
  179.     }
  180.     bool operator == (const char* str) const { 
  181.     return strcmp((char*)data, str) == 0; 
  182.     }
  183.     bool operator != (const char* str) const { 
  184.     return strcmp((char*)data, str) != 0; 
  185.     }
  186.     unsigned hash() const { 
  187.     return string_hash_function(data);
  188.     }
  189.     int  first_char() const { return data[0]; }
  190.  
  191.     void operator = (utf_string const& str) { 
  192.     len = str.len;
  193.     data = str.data;
  194.     }
  195.  
  196.     utf_string operator + (const char* suffix) const { 
  197.     utf_string str;
  198.     str.len = len + strlen(suffix);
  199.     str.data = new byte[str.len+1];
  200.     memcpy(str.data, data, len);
  201.     memcpy(str.data+len, suffix, str.len - len);
  202.     str.data[str.len] = 0; // zero terminated string
  203.     return str;
  204.     }
  205.  
  206.     void append(int offs, utf_string const& suffix) { 
  207.     assert(offs <= len);
  208.     len = offs + suffix.len;
  209.     byte* new_data = new byte[len+1];
  210.     memcpy(new_data, data, offs);
  211.     memcpy(new_data+offs, suffix.data, suffix.len);
  212.     new_data[len] = 0; // zero terminated string
  213.     delete[] data;
  214.     data = new_data;
  215.     }
  216.  
  217.     int rindex(byte ch) const { 
  218.     byte* p = (byte*)strrchr((char*)data, ch);
  219.     return p ? p - data : -1;
  220.     }
  221.  
  222.     void set_size(int size) { len = size; }
  223.  
  224.     char* as_asciz() const { return (char*)data; }
  225.  
  226.     utf_string(int length, byte* str) { 
  227.     len = length;
  228.     data = new byte[length+1];
  229.     memcpy(data, str, length);
  230.     data[length] = 0;
  231.     }
  232.     utf_string(const char* str) { 
  233.     len = strlen(str);
  234.     data = (byte*)str;
  235.     }
  236.  
  237.     utf_string(utf_string const& str) { 
  238.     len = str.len;
  239.     data = str.data;
  240.     }
  241.     utf_string() { len = 0; data = NULL; }
  242. };
  243.  
  244.     
  245. class method_desc;
  246. class field_desc;
  247. class class_desc;
  248. class constant;
  249.  
  250. class callee_desc {
  251.   public:
  252.     class_desc*    self_class;
  253.     method_desc*   method;
  254.     callee_desc*   next;
  255.     void*          backtrace;
  256.     int            line;
  257.     int            attr;
  258.     enum { 
  259.     i_self          = 0x01, // invoke method of self class
  260.     i_synchronized  = 0x02, // method os invoked from synchronized(){} body
  261.     i_wait_deadlock = 0x04  // invocation can cause deadlock in wait()
  262.     };
  263.     
  264.  
  265.     void message(int msg_code, ...); 
  266.     
  267.     callee_desc(class_desc* cls, method_desc* mth, callee_desc* chain, 
  268.            int lineno, int call_attr) 
  269.     { 
  270.         self_class = cls;  
  271.     method = mth;
  272.     next = chain;
  273.     line = lineno;
  274.     attr = call_attr;
  275.     backtrace = NULL; 
  276.     }
  277. };
  278.  
  279. class access_desc { 
  280.   public: 
  281.     access_desc*   next;
  282.     class_desc*    self_class;
  283.     field_desc*    field;
  284.     int            line;
  285.     int            attr;
  286.     enum { 
  287.     a_self = 0x01, // access to the component of the same class
  288.     a_new  = 0x02  // field of newly created object is accessed
  289.     };
  290.  
  291.     void message(int msg_code, ...); 
  292.  
  293.     access_desc(field_desc* desc, class_desc* cls, 
  294.         int lineno, access_desc* chain)
  295.     { 
  296.     field = desc;
  297.     next = chain;
  298.     self_class = cls;
  299.     line = lineno;
  300.     attr = 0;
  301.     }    
  302. };
  303.  
  304. class graph_vertex;
  305.  
  306. class graph_edge { 
  307.   public:
  308.     graph_edge*   next;
  309.     callee_desc*  invocation;
  310.     method_desc*  caller;
  311.     graph_vertex* vertex;
  312.     int           mask;
  313.  
  314.     void message(int loop_id);
  315.  
  316.     graph_edge(graph_vertex* node, method_desc* method, callee_desc* call) { 
  317.     invocation = call;
  318.     caller = method;
  319.     vertex = node;
  320.     mask = 0;
  321.     }
  322. };
  323.  
  324. class graph_vertex { 
  325.   public:
  326.     graph_edge*   edges;
  327.     graph_vertex* next;
  328.     class_desc*   cls;
  329.     int           visited;
  330.     int           marker;
  331.     int           n_loops;
  332.     enum { 
  333.     flag_vertex_on_path    = 0x80000000,
  334.     flag_vertex_not_marked = 0x7fffffff
  335.     };
  336.     
  337.  
  338.  
  339.     static int    n_vertexes;
  340.  
  341.     static graph_vertex* graph;
  342.     
  343.     static void verify();
  344.  
  345.     void attach(graph_edge* edge) { 
  346.     edge->next = edges;
  347.     edges = edge;
  348.     }
  349.  
  350.     graph_vertex(class_desc* vertex_class) { 
  351.     cls = vertex_class;
  352.     visited = 0;
  353.     marker = flag_vertex_not_marked;
  354.     next = graph;
  355.     graph = this;
  356.     edges = NULL;
  357.     n_vertexes += 1;
  358.     }
  359. };
  360.  
  361. class var_desc { 
  362.   public:
  363.     utf_string     name;
  364.     int            type;
  365.     int            start_pc;
  366.     
  367.     int4           min;
  368.     int4           max;
  369.     int4           mask;
  370.  
  371.     enum object_var_state {
  372.     vs_unknown  = 0x01, // state of variable is unknown
  373.     vs_not_null = 0x03, // variable was checked for null
  374.     vs_new      = 0x04  // variable points to object created by new
  375.     };
  376. };
  377.  
  378. class component_desc { 
  379.   public:
  380.     utf_string     name;
  381.     class_desc*    cls;
  382.     class_desc*    accessor;
  383.     
  384.     component_desc(utf_string const& component_name, class_desc* component_cls)
  385.     : name(component_name), cls(component_cls), accessor(NULL) {}
  386. };
  387.     
  388.  
  389. class field_desc : public component_desc { 
  390.   public:
  391.     field_desc*    next;
  392.     int            attr;
  393.     enum { 
  394.     f_static     = 0x0008, 
  395.     f_final      = 0x0010,
  396.     f_volatile   = 0x0040, 
  397.     
  398.     f_used       = 0x10000,
  399.         f_serialized = 0x20000 // field is accessed only from methods 
  400.                            // of related classes
  401.  
  402.     };
  403.  
  404.     field_desc(utf_string const& field_name, class_desc* owner, 
  405.            field_desc* chain) 
  406.     : component_desc(field_name, owner)
  407.     {
  408.     next = chain; 
  409.     attr = f_serialized;
  410.     }
  411. };
  412.  
  413. struct vbm_operand { 
  414.     int  type;  // type of expression/variable before it was pushed in stack
  415.     int4 max;   // maximal value of operand
  416.     int4 min;   // minimal value of operand
  417.     int4 mask;  // mask of possible set bits and zero value indicator for 
  418.                 // object types
  419.     int  index; // index of local veriable, which value was loaded in stack
  420. };
  421.  
  422.  
  423. class local_context { 
  424.   public:
  425.     enum context_cmd { 
  426.     cmd_pop_var,    // start of local variable scope
  427.     cmd_push_var,   // end of local variable scope
  428.     cmd_merge_ctx,  // forward jump label
  429.     cmd_reset_ctx,  // backward jump label
  430.     cmd_enter_ctx,  // entry point
  431.     cmd_case_ctx,   // switch case label
  432.     cmd_update_ctx, // backward jump
  433.     cmd_save_ctx    // forward jump
  434.     } cmd;
  435.  
  436.     local_context* next;
  437.  
  438.     virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp, 
  439.                   byte cop, byte& prev_cop) = 0;
  440.  
  441.     local_context(context_cmd ctx_cmd, local_context** chain) { 
  442.     cmd = ctx_cmd;
  443.     while (*chain != NULL && (*chain)->cmd < ctx_cmd) { 
  444.         chain = &(*chain)->next;
  445.     }
  446.     next = *chain;
  447.     *chain = this;
  448.     }
  449. };
  450.  
  451. class ctx_pop_var : public local_context { 
  452.   public:
  453.     int var_index;
  454.  
  455.     ctx_pop_var(local_context** chain, int index) 
  456.     : local_context(cmd_pop_var, chain), var_index(index) {}
  457.  
  458.     virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp, 
  459.                   byte cop, byte& prev_cop);
  460. };
  461.  
  462.  
  463. class ctx_push_var : public local_context { 
  464.   public:
  465.     utf_string* var_name;
  466.     int         var_type;
  467.     int         var_index;
  468.     int         var_start_pc;
  469.     
  470.     ctx_push_var(local_context** chain,
  471.          utf_string* name, int type, int index, int start_pc)
  472.     : local_context(cmd_push_var, chain) {
  473.     var_name = name; 
  474.     var_type = type;
  475.     var_index = index;
  476.     var_start_pc = start_pc;
  477.     }
  478.     
  479.  
  480.     virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp, 
  481.                   byte cop, byte& prev_cop);
  482. };
  483.     
  484.  
  485. class ctx_split : public local_context { 
  486.   public: 
  487.     var_desc*    vars; 
  488.     vbm_operand* stack_pointer;
  489.     vbm_operand  stack_top[2];
  490.     int          switch_var_index;
  491.     int          n_branches;
  492.     
  493.     enum jmp_type { jmp_forward, jmp_backward };
  494.  
  495.     ctx_split(local_context** chain, jmp_type type = jmp_forward) 
  496.     : local_context(type == jmp_forward ? cmd_save_ctx : cmd_update_ctx, chain)
  497.     {
  498.     n_branches = 1;
  499.     }
  500.     
  501.     virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp, 
  502.                   byte cop, byte& prev_cop);
  503. };
  504.     
  505.     
  506. class ctx_merge : public local_context { 
  507.   public:
  508.     ctx_split* come_from;
  509.     int        case_value;
  510.     
  511.     ctx_merge(local_context** chain, ctx_split* come_from_ctx) 
  512.     : local_context(cmd_merge_ctx, chain) 
  513.     { 
  514.     come_from = come_from_ctx;
  515.     }
  516.  
  517.     ctx_merge(local_context** chain, ctx_split* come_from_ctx, int value) 
  518.     : local_context(cmd_case_ctx, chain) 
  519.     {
  520.     come_from = come_from_ctx;
  521.     case_value = value;
  522.     }
  523.   
  524.     virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp, 
  525.                   byte cop, byte& prev_cop);
  526. };
  527.  
  528.  
  529. class ctx_entry_point : public local_context { 
  530.   public:
  531.     ctx_entry_point(local_context** chain)
  532.     : local_context(cmd_enter_ctx, chain) {}
  533.     
  534.     virtual vbm_operand* transfer(method_desc* method, 
  535.                   vbm_operand* sp, byte cop, byte& prev_cop);
  536. };
  537.  
  538. class ctx_reset : public local_context { 
  539.   public:
  540.     int* var_store_count;
  541.     
  542.     ctx_reset(local_context** chain, int* counts, int n_vars) 
  543.     : local_context(cmd_reset_ctx, chain) 
  544.     { 
  545.     var_store_count = new int[n_vars];
  546.     memcpy(var_store_count, counts, n_vars*sizeof(int));
  547.     }
  548.     
  549.     virtual vbm_operand* transfer(method_desc* method, vbm_operand* sp, 
  550.                   byte cop, byte& prev_cop);
  551. };
  552.  
  553. class overridden_method { 
  554.   public:
  555.     overridden_method* next;
  556.     method_desc*       method;
  557.  
  558.     overridden_method(method_desc* mth, overridden_method* chain) { 
  559.     method = mth;
  560.     next = chain;
  561.     }
  562. };
  563.  
  564. class method_desc : public component_desc { 
  565.   public:
  566.     utf_string     desc;
  567.     method_desc*   next;
  568.  
  569.     int attr;
  570.     enum { 
  571.     m_static       = 0x0008,
  572.     m_final        = 0x0010,
  573.     m_synchronized = 0x0020,
  574.     m_native       = 0x0100,
  575.     m_abstract     = 0x0400,
  576.  
  577.     m_wait         = 0x010000, // invoke wait()
  578.     m_serialized   = 0x020000, // method is called only from methods 
  579.                                // of related classes
  580.     m_concurrent   = 0x040000, // Method is either run of Runanble protcol
  581.                                // or synchronized or called from them.
  582.     m_visited      = 0x080000, // Used while recursive traversal of methods
  583.     m_deadlock_free= 0x100000, // Doesn't call any synchronized methods
  584.     m_override     = 0x200000  // Override method of base class
  585.     };
  586.  
  587.     int            n_vars;
  588.     var_desc*      vars;
  589.     int*           var_store_count;
  590.  
  591.     bool           local_variable_table_present;
  592.  
  593.     callee_desc*   callees;
  594.     access_desc*   accessors;
  595.     
  596.     graph_vertex*  vertex;
  597.  
  598.     //
  599.     // Chain of methods from derived classes, overriding this method
  600.     //
  601.     overridden_method* overridden; 
  602.  
  603.     //
  604.     // 1 bit in position 'i' of 'null_parameter_mask' means that NULL is 
  605.     // passed as the value of parameter 'i'
  606.     //
  607.     unsigned       null_parameter_mask; 
  608.     //
  609.     // 1 bit in position 'i' of 'unchecked_use_mask' means that formal
  610.     // parameter 'i' is used without check for NULL
  611.     //
  612.     unsigned       unchecked_use_mask;    
  613.  
  614.     int            code_length;
  615.     byte*          code;
  616.  
  617.     local_context**context;
  618.  
  619.     int            first_line; // line corresponing to first method instruction
  620.     int            wait_line;  // line of last wait() invocation in the method
  621.     word*          line_table;
  622.  
  623.     int  demangle_method_name(char* buf);
  624.  
  625.     void calculate_attributes();
  626.  
  627.     void find_access_dependencies();
  628.  
  629.     void build_concurrent_closure();
  630.     void add_to_concurrent_closure(callee_desc* caller, 
  631.                    int call_attr, int depth);
  632.  
  633.     void build_call_graph();
  634.     bool build_call_graph(method_desc* caller, callee_desc* callee,
  635.               int call_attr);
  636.  
  637.     int  print_call_path_to(callee_desc* target, int loop_id, int path_id, 
  638.                 int call_attr = 0, callee_desc* prev = NULL);
  639.  
  640.     void check_synchronization();
  641.     void check_invocations();
  642.  
  643.     bool is_special_method() { return name.first_char() == '<'; }
  644.  
  645.     int  get_line_number(int pc);
  646.     void message(int msg_code, int pc, ...);
  647.  
  648.     void check_variable_for_null(int pc, vbm_operand* sp); 
  649.     void check_array_index(int pc, vbm_operand* sp); 
  650.  
  651.     void basic_blocks_analysis();
  652.  
  653.     void parse_code(constant** constant_pool);
  654.  
  655.     method_desc(utf_string const& mth_name, utf_string const& mth_desc, 
  656.         class_desc* cls_desc, method_desc* chain) 
  657.     : component_desc(mth_name, cls_desc), desc(mth_desc)
  658.     { 
  659.     callees = NULL;
  660.     accessors = NULL;
  661.     attr = m_serialized;
  662.     next = chain;
  663.     first_line = 0;
  664.     overridden = NULL;
  665.     local_variable_table_present = false;
  666.     null_parameter_mask = unchecked_use_mask = 0;
  667.     }
  668. };
  669.  
  670. class class_desc { 
  671.   public:
  672.     utf_string     name;
  673.     utf_string     source_file;
  674.     class_desc*    next;
  675.     class_desc*    collision_chain; 
  676.  
  677.     method_desc*   methods;
  678.  
  679.     int            attr; 
  680.     enum class_attrs { 
  681.     cl_interface = 0x00200,
  682.  
  683.         cl_system    = 0x10000        
  684.     };
  685.  
  686.     int            n_bases;
  687.     class_desc**   bases;
  688.  
  689.     field_desc*    fields;
  690.  
  691.     graph_vertex*  class_vertex;
  692.     graph_vertex*  metaclass_vertex;
  693.  
  694.     static class_desc* get(utf_string const& str);
  695.  
  696.     method_desc* get_method(utf_string const& mth_name, 
  697.                 utf_string const& mth_desc);
  698.  
  699.     field_desc* get_field(utf_string const& field_name);
  700.  
  701.     static class_desc* hash_table[];
  702.     static int         n_classes;
  703.     static class_desc* chain;
  704.  
  705.     bool isa(const char* cls_name);
  706.     bool isa(class_desc* cls);
  707.     bool implements(const char* interface_name);
  708.     bool in_relationship_with(class_desc* cls);
  709.  
  710.     void verify();
  711.     void calculate_attributes();
  712.     void build_class_info();
  713.     void build_call_graph();
  714.     void build_concurrent_closure();
  715.     void check_inheritance(class_desc* derived);
  716.  
  717.     static void global_analysis();
  718.  
  719.     class_desc(utf_string const& str);
  720. };
  721.  
  722.  
  723. enum const_types { 
  724.     c_none,
  725.     c_utf8,
  726.     c_reserver,
  727.     c_integer,
  728.     c_float,
  729.     c_long,
  730.     c_double, 
  731.     c_class,
  732.     c_string,
  733.     c_field_ref,
  734.     c_method_ref,
  735.     c_interface_method_ref,
  736.     c_name_and_type
  737. };
  738.  
  739. class constant { 
  740.   public:
  741.     byte tag;
  742.     virtual int length() = 0;
  743.     virtual type_tag type() { return tp_object; }
  744.     constant(byte* p) { tag = *p; }
  745. };
  746.  
  747.  
  748. class const_utf8 : public constant, public utf_string { 
  749.   public:
  750.     const_utf8(byte* p) : constant(p), utf_string(unpack2(p+1), p+3) {}
  751.     int length() { return 3 + len; }
  752. };
  753.  
  754. class const_int : public constant {
  755.   public:
  756.     int value;
  757.     const_int(byte* p) : constant(p) {
  758.     value = unpack4(p+1);
  759.     }
  760.     int length() { return 5; }
  761.     type_tag type() { return tp_int; }
  762. };
  763.  
  764. class const_float : public constant {
  765.   public:
  766.     const_float(byte* p) : constant(p) {}
  767.     int length() { return 5; }
  768.     type_tag type() { return tp_float; }
  769. };
  770.  
  771. class const_long : public constant {
  772.   public:
  773.     struct { 
  774.     int4 high;
  775.     int4 low;
  776.     } value;
  777.     const_long(byte* p) : constant(p) {
  778.     value.high = unpack4(p+1);
  779.     value.low  = unpack4(p+5);
  780.     }
  781.     int length() { return 9; }
  782.     type_tag type() { return tp_long; }
  783. };
  784.  
  785. class const_double : public constant {
  786.   public:
  787.     const_double(byte* p) : constant(p) {}
  788.     int length() { return 9; }
  789.     type_tag type() { return tp_double; }
  790. };
  791.  
  792. class const_class : public constant {
  793.    public:   
  794.     int name;
  795.     const_class(byte* p) : constant(p) {
  796.     name = unpack2(p+1);
  797.     }
  798.     int length() { return 3; }
  799. };
  800.  
  801. class const_string : public constant {
  802.    public:   
  803.     int str;
  804.     const_string(byte* p) : constant(p) {
  805.     str = unpack2(p+1);
  806.     }
  807.     int length() { return 3; }
  808.     type_tag type() { return tp_string; }
  809. };
  810.  
  811. class const_ref : public constant {
  812.    public:   
  813.     int cls;
  814.     int name_and_type;
  815.     const_ref(byte* p) : constant(p) {
  816.     cls = unpack2(p+1);
  817.     name_and_type = unpack2(p+3);
  818.     }
  819.     int length() { return 5; }
  820. };
  821.  
  822.  
  823. class const_name_and_type : public constant {
  824.    public:   
  825.     int name;
  826.     int desc;
  827.     const_name_and_type(byte* p) : constant(p) {
  828.     name = unpack2(p+1);
  829.     desc = unpack2(p+3);
  830.     }
  831.     int length() { return 5; }
  832. };
  833.  
  834. //
  835. // Constants for extracting zip file
  836. //
  837.  
  838. #define LOCAL_HDR_SIG     "\113\003\004"   /*  bytes, sans "P" (so unzip */
  839. #define LREC_SIZE     26    /* lengths of local file headers, central */
  840. #define CREC_SIZE     42    /*  directory headers, and the end-of-    */
  841. #define ECREC_SIZE    18    /*  central-dir record, respectively      */
  842. #define TOTAL_ENTRIES_CENTRAL_DIR  10
  843. #define SIZE_CENTRAL_DIRECTORY     12
  844. #define C_UNCOMPRESSED_SIZE        20
  845. #define C_FILENAME_LENGTH          24
  846. #define C_EXTRA_FIELD_LENGTH       26
  847. #define C_RELATIVE_OFFSET_LOCAL_HEADER    38
  848. #define L_FILENAME_LENGTH                 22
  849. #define L_EXTRA_FIELD_LENGTH              24
  850.  
  851. #endif
  852.  
  853.  
  854.